Статистический анализ в R и Pyhton

Графические средства представления данных в R, Python

Подгрузка данных (Python code)

import pandas as pd
# openpyxl
df = pd.read_excel(
    io = "crimes.xlsx",
    sheet_name = 0,
    header = 2
)

sbnm = sorted(
    set([match[0] for match in df.columns.str.findall(
        r'\d{4}').values if match != []]) )

df = pd.melt(
    frame = df,
    id_vars= df.columns[:3],
    value_vars= sbnm,
    var_name = 'Год'
).dropna()

df = df.astype({'Год': 'int'})
df = df.rename(columns={"Справочник территорий РФ": "ОКАТО"})
import re
df = df[
    (df['Период'] == '118 январь-декабрь')&
    # Фильтрация по субъектам РФ, у которых 11 значный код
    (df['ОКАТО'].apply(lambda x:bool(re.search(r'\d{11}', x))))
    ]

df.columns

Подгрузка данных (Python code)

Index(['Единица измерения', 'Период', 'ОКАТО', 'Год', 'value'], dtype='object')
df
     Единица измерения              Период  ...   Год    value
107        642 единица  118 январь-декабрь  ...  2008   6037.0
108        642 единица  118 январь-декабрь  ...  2008   7038.0
109        642 единица  118 январь-декабрь  ...  2008   5023.0
110        642 единица  118 январь-декабрь  ...  2008  10436.0
111        642 единица  118 январь-декабрь  ...  2008   4421.0
...                ...                 ...  ...   ...      ...
3142       642 единица  118 январь-декабрь  ...  2022   5775.0
3143       642 единица  118 январь-декабрь  ...  2022    748.0
3144       642 единица  118 январь-декабрь  ...  2022   3154.0
3145       642 единица  118 январь-декабрь  ...  2022   1094.0
3146       642 единица  118 январь-декабрь  ...  2022    305.0

[1308 rows x 5 columns]

Гистограмма распределения (Python code)

import matplotlib.pyplot as plt

# plot:
df['value'].hist()
plt.show()

Гистограмма распределения (Python code)

Группировка с равными интервалами (Python code)

import numpy as np
import scipy.stats as stats

plt.clf()
df_plt = df.query('Год==2022').value

df_plt_bins = pd.DataFrame(pd.cut(df_plt, bins=5).value_counts())
df_plt_bins['cumul'] = np.cumsum(df_plt_bins['count'])

df_plt_bins
                    count  cumul
value                           
(224.628, 4922.4]      37     37
(4922.4, 9596.8]       26     63
(14271.2, 18945.6]     11     74
(9596.8, 14271.2]      10     84
(18945.6, 23620.0]      4     88

Группировка с равными интервалами (Python code)

#строим их на одном графике
plt.hist(df_plt, density=1, bins=5)
plt.show()

Полигон (Python code)

plt.clf()
df_plt_bins['count'].plot()
plt.show()

Полигон (Python code)

Кумулята (Python code)

plt.clf()
df_plt_bins['cumul'].plot()
plt.show()

Кумулята (Python code)

Ящичковая диаграмма (Python code)

plt.clf()
df_plt = df[['Год', 'value']].query('Год in (2008,2022)')
df_plt.boxplot(by='Год')
plt.show()

Ящичковая диаграмма (Python code)

Ящичковая диаграмма

Ящичковая диаграмма

Скрипичная диаграмма (Python code)

# plot:
plt.clf()
# plot:
fig, ax = plt.subplots()

vp = ax.violinplot(df['value'])

# styling:

plt.show()

Скрипичная диаграмма (Python code)

Ряд динамики (Python code)

plt.clf()
df_plt = df.query('ОКАТО=="450000000001 г. Москва"')[['Год', 'value']]
df_plt.plot('Год', 'value')
plt.show()

Ряд динамики (Python code)

Диаграмма рассеяния (Python code)

plt.clf()
df = pd.read_csv("regressionlab_1.csv", index_col=0, sep=";")

plt.scatter(df['issue'], df['adcost'])
plt.show()

Диаграмма рассеяния (Python code)

Настройка графика - подписи (Python code)

# plt.clf()

fig, ax = plt.subplots()
ax.scatter('issue', 'adcost', data=df)
ax.set_title('Диаграмма рассеяния')
ax.set_xlabel('тираж, тыс.экз.')
ax.set_ylabel('стоимость рекламы, руб.')
ax.legend()
plt.show()

Настройка графика - подписи (Python code)

Настройка графика - Цвет, размер (Python code)

fig, ax = plt.subplots(figsize=(5, 2.7))
ax.scatter('issue', 'adcost', data=df, s=50, facecolor='y', edgecolor='k')

plt.show()
  • ‘b’ as blue
  • ‘g’ as green
  • ‘r’ as red
  • ‘c’ as cyan
  • ‘m’ as magenta
  • ‘y’ as yellow
  • ‘k’ as black
  • ‘w’ as white

Настройка графика - Цвет, размер (Python code)

Настройка графика - добавление текста (Python code)

fig, ax = plt.subplots()
ax.scatter('issue', 'adcost', data=df)
ax.text(20, 30000, 'точки рассеяния')
plt.show()

Настройка графика - добавление текста (Python code)

Настройка графика - стиль (Python code)

fig, ax = plt.subplots()
ax.scatter('issue', 'adcost', data = df, marker="^", s=80)
plt.show()

Настройка графика - масштаб оси (Python code)

fig, ax = plt.subplots()
ax.scatter('issue', 'adcost', data = df)
ax.set_xticks([20, 60, 140])
ax.set_yticks([5000, 20000, 35000])
plt.show()

Подгрузка данных (R code)

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.3     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.3     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
df <- readxl::read_excel(
    path = "crimes.xlsx",
    sheet = 1,
    skip = 2
  ) |> 
  pivot_longer(
    cols = matches("\\d{4}"),
    names_to = "Год",
    names_transform = list( `Год` = as.integer),
    values_to = "value"
  ) |> 
  drop_na() |>
  rename( `ОКАТО` = `Справочник территорий РФ` ) |>
  filter(
    `Период` == '118 январь-декабрь',
    str_detect(`ОКАТО`, "\\d{11}")
  )

df
# A tibble: 1,308 × 5
   `Единица измерения` Период             ОКАТО                        Год value
   <chr>               <chr>              <chr>                      <int> <dbl>
 1 642 единица         118 январь-декабрь 140000000001 Белгородская…  2008  6037
 2 642 единица         118 январь-декабрь 140000000001 Белгородская…  2009  5869
 3 642 единица         118 январь-декабрь 140000000001 Белгородская…  2010  5315
 4 642 единица         118 январь-декабрь 140000000001 Белгородская…  2011  4571
 5 642 единица         118 январь-декабрь 140000000001 Белгородская…  2012  4006
 6 642 единица         118 январь-декабрь 140000000001 Белгородская…  2013  4196
 7 642 единица         118 январь-декабрь 140000000001 Белгородская…  2014  4115
 8 642 единица         118 январь-декабрь 140000000001 Белгородская…  2015  4886
 9 642 единица         118 январь-декабрь 140000000001 Белгородская…  2016  4336
10 642 единица         118 январь-декабрь 140000000001 Белгородская…  2017  4253
# ℹ 1,298 more rows

Гистограмма распределения (R code)

ggplot(df, aes(x=value)) + 
    geom_histogram()

Гистограмма распределения (R code)

Группировка с равными интервалами (R code)

df_plt <- filter(df, `Год` == 2022) |> 
  pull(value) |>
  # dig.lab количество отображаемых чисел
  cut(breaks=5, dig.lab = 8) |> 
  vctrs::vec_count(sort = "key") |> 
  tibble() |> mutate( cumul = cumsum(count) )

df_plt
# A tibble: 5 × 3
  key                 count cumul
  <fct>               <int> <int>
1 (224.628,4922.4]       37    37
2 (4922.4,9596.8]        26    63
3 (9596.8,14271.2]       10    73
4 (14271.2,18945.6]      11    84
5 (18945.6,23643.372]     4    88

Группировка с равными интервалами (R code)

ggplot(data=df_plt, aes(x=key, y=count)) +
    geom_col()

Полигон (R code)

ggplot(data=df_plt, aes(key, count, group = 1)) +
  geom_point()+
  geom_line()

Полигон (R code)

Кумулята (R code)

ggplot(data=df_plt, aes(key, cumul, group = 1)) +
  geom_point()+
  geom_line()

Кумулята (R code)

Ящичковая диаграмма (R code)

df |> 
  filter(
    `Год` %in% c(2008,2022)
  ) |> 
  mutate(`Год` = as.character(`Год`) ) -> df_plt

ggplot(data=df_plt, aes( x = `Год`,group = `Год`,  y = value)) +
  geom_boxplot()

Ящичковая диаграмма (R code)

Скрипичная диаграмма (R code)

# plot:
ggplot(data=df_plt, aes( x = `Год`,group = `Год`,  y = value) ) + 
  geom_violin()

Скрипичная диаграмма (R code)

Ряд динамики (R code)

df |> 
  filter( `ОКАТО` == "450000000001 г. Москва" ) |> 
  select(`Год`, value) -> df_plt

ggplot(data=df_plt, aes( x = `Год`, y = value)) +
  geom_line()

Ряд динамики (R code)

Диаграмма рассеяния (R code)

df <- read.csv("regressionlab_1.csv", sep = ";") |> tibble()

ggplot(data=df, aes( x = issue, y = adcost)) +
  geom_point() 

Настройка графика - подписи (R code)

ggplot(data=df, aes( x = issue, y = adcost)) +
  geom_point() +
  labs(
    title = 'Диаграмма рассеяния',
    x = 'тираж, тыс.экз.',
    y = 'стоимость рекламы, руб.'
  )

Настройка графика - подписи (R code)

Настройка графика - Цвет, размер (R code)

ggplot(data=df, aes( x = issue, y = adcost)) +
  geom_point( color="yellow", size = 10)

Настройка графика - Цвет, размер (R code)

Настройка графика - добавление текста (R code)

ggplot(data=df, aes( x = issue, y = adcost)) +
  geom_point() +
  annotate(geom="text", x=20, y=30000, label="точки рассеяния")

Настройка графика - добавление текста (R code)

Настройка графика - стиль (R code)

ggplot(data=df, aes( x = issue, y = adcost)) +
  geom_point(shape=23, size = 3) 

Настройка графика - стиль (R code)

Настройка графика - масштаб оси (R code)

ggplot(data=df, aes( x = issue, y = adcost)) +
  geom_point() +
  scale_x_continuous(breaks = c(20, 60, 140) ) +
  scale_y_continuous(breaks = c(5000, 20000, 35000) )

Настройка графика - масштаб оси (R code)

Подгрузка данных многомерных данных

df = pd.read_csv("iris.csv")
df
     sepal.length  sepal.width  petal.length  petal.width    variety
0             5.1          3.5           1.4          0.2     Setosa
1             4.9          3.0           1.4          0.2     Setosa
2             NaN          3.2           1.3          0.2     Setosa
3             4.6          3.1           1.5          0.2     Setosa
4             5.0          3.6           1.4          0.2     Setosa
..            ...          ...           ...          ...        ...
145           6.7          3.0           5.2          2.3  Virginica
146           6.3          2.5           5.0          1.9  Virginica
147           6.5          3.0           5.2          2.0  Virginica
148           6.2          3.4           5.4          2.3  Virginica
149           5.9          3.0           5.1          1.8  Virginica

[150 rows x 5 columns]
df <- read.csv("iris.csv") |> tibble()
df
# A tibble: 150 × 5
   sepal.length sepal.width petal.length petal.width variety
          <dbl>       <dbl>        <dbl>       <dbl> <chr>  
 1          5.1         3.5          1.4         0.2 Setosa 
 2          4.9         3            1.4         0.2 Setosa 
 3         NA           3.2          1.3         0.2 Setosa 
 4          4.6         3.1          1.5         0.2 Setosa 
 5          5           3.6          1.4         0.2 Setosa 
 6          5.4         3.9          1.7         0.4 Setosa 
 7          4.6         3.4          1.4         0.3 Setosa 
 8          5           3.4          1.5         0.2 Setosa 
 9          4.4         2.9          1.4         0.2 Setosa 
10          4.9         3.1          1.5         0.1 Setosa 
# ℹ 140 more rows

Многомерное распределения (Python code)

График представляет собой трехмерное изображение многомерного распределения в 3-х мерном пространстве.

plt.clf()

fig = plt.figure(figsize=(8,9))
ax = plt.axes(projection='3d')

ax.scatter(
  df['sepal.length'], df['sepal.width'],
  df['petal.width']
  )
ax.view_init(40, 50) #повернуть график
plt.show()

Многомерное распределения (Python code)

Многомерное распределения (R code)

library("scatterplot3d")

scatterplot3d(df[,1:3], angle = 55)

Многомерное распределения (R code)

Тепловая диаграмма

Тепловая диаграмма представляет наглядное отображение результатов иерархического кластерного анализа. При этом по одной оси возможно отобразить кластеризацию переменных, а по другой – наблюдений.

В случае, когда по обеим осям отображаются либо переменные, либо наблюдения, тепловая диаграмма позволяет более конкретно определить возможные группы или выбросы в данных.

Если по одной оси располагается иерархическая кластеризация переменных, а по другой – наблюдений, возможно выявить группы наиболее похожих или связанных наблюдений и переменных (например, какие именно наблюдения больше всего схожи по каким параметрам, а по каким – различаются)

Тепловая диаграмма (Python code)

import seaborn as sns
plt.clf()
df.dropna(how="any", inplace=True)
sns.clustermap(df.select_dtypes(include=float))

Тепловая диаграмма (Python code)

plt.show()

Тепловая диаграмма (R code)

library(pheatmap) ## for heatmap generation

pheatmap( select( df, where(is.double) ) )

Тепловая диаграмма (R code)

Уровневая диаграмма

Является альтернативным и более совершенным графическим методом представления данных для диаграммы рассеяния, с добавлением третьей координаты в виде цвета.

В данном примере уровневая диаграмма рассеяния позволяет изобразить сразу четыре фактора: первые две переменные (sepal width и sepal length) это координатные оси Х и У, размер точки соответствует величине третьей переменной (petal width), а цвет – категория (вид).

Уровневая диаграмма (Python code)

plt.clf()
target = pd.factorize(df.variety)[0]

plt.scatter(
  df['sepal.width'], 
  df['sepal.length'], 
  alpha=0.2, s=100*df['petal.width'], 
  c=target, cmap='viridis' )
plt.show()

Уровневая диаграмма (Python code)

Уровневая диаграмма (R code)

ggplot(
  data=df, 
  aes( 
    x = sepal.width, 
    y = sepal.length, 
    color = variety, 
    size = petal.width ) 
  ) +
  geom_point() 

Уровневая диаграмма (R code)

Контурная диаграмма (Python code)

Контурная диаграмма представляет «вид сверху» многомерного распределения, позволяя наглядно отобразить пики и провалы в многомерном распределении данных.

plt.clf()
sns.kdeplot(
  data = df,
  x = 'sepal.width', 
  y = 'sepal.length', cmap="seismic", 
  cbar=True, fill=True, thresh=0
  )
plt.show()

Контурная диаграмма (Python code)

Контурная диаграмма (R code)

ggplot(df, aes(x = sepal.width, y = sepal.length)) +
  geom_density_2d_filled()

Контурная диаграмма (R code)